﻿@*
//------------------------------------------------------------------------------
//  此代码版权声明为全文件覆盖，如有原作者特别声明，会在下方手动补充
//  此代码版权（除特别声明外的代码）归作者本人Diego所有
//  源代码使用协议遵循本仓库的开源协议及附加协议
//  Gitee源代码仓库：https://gitee.com/diego2098/ThingsGateway
//  Github源代码仓库：https://github.com/kimdiego2098/ThingsGateway
//  使用文档：https://diego2098.gitee.io/thingsgateway-docs/
//  QQ群：605534569
//------------------------------------------------------------------------------
*@

@using BlazorComponent;
@using Microsoft.AspNetCore.Components.Web;
@using System.Reflection;
@using ThingsGateway.Foundation.Adapter.OPCDA;
@using ThingsGateway.Foundation;
@using ThingsGateway.Foundation.Adapter.OPCDA.Rcw;
@using ThingsGateway.Web.Foundation;
@using Masa.Blazor
@using Yitter.IdGenerator;
<MCard Class="ma-0">
    <MCardTitle Class="indigo white--text text-h6">
        @PLC?.OPCNode?.ToString()
    </MCardTitle>
    <MRow Class="pa-4"
          Justify="JustifyTypes.SpaceBetween">
        <MCol Cols="12" Md="6">
            <MTreeview @bind-Value=_selected @bind-Active=_actived SelectionType="SelectionType.Leaf"
                       Items=Nodes TItem=OPCDATagModel
                       Color="warning" Selectable Activatable OpenOnClick
                       LoadChildren=PopulateBranchAsync
                       TKey=BrowseElement ItemKey="r=>r.Tag"
                       Style="height:500px;overflow-y:auto;"
                       ItemText="r=>r.Name"
                       ItemChildren="r=>r.Nodes">

            </MTreeview>

        </MCol>
        <MCol Cols="12" Md="6">
            <MCardText Style="height:500px;overflow-y:auto;">
                @if (_actived?.Count == 0)
                {
                    <div key="title"
                         class="text-h6 font-weight-light grey--text pa-4 text-center">
                        选择左侧节点
                    </div>
                }
                else
                {
                    <ScrollXTransition>
                        <MSheet Outlined Class="ma-0 pa-1">
                            <MRow Align="AlignTypes.Center">
                                <MCol>
                                    <MListItem>
                                        <ItemContent>
                                            <MListItemContent>
                                                <MListItemTitle>NodeId </MListItemTitle>
                                            </MListItemContent>
                                        </ItemContent>
                                    </MListItem>
                                </MCol>
                                <MDivider Vertical Center />
                                <MCol>
                                    <MLabel Class=@($"ma-1")> @_actived.FirstOrDefault().ItemName  </MLabel>
                                </MCol>

                            </MRow>
                        </MSheet>
                        @if (nodeAttributes != null)
                        {
                            @foreach (var item in nodeAttributes)
                            {
                                <MSheet Outlined Class="ma-0 pa-1">
                                    <MRow Align="AlignTypes.Center">
                                        <MCol>
                                            <MListItem>
                                                <ItemContent>
                                                    <MListItemContent>
                                                        <MListItemTitle>@item.Description </MListItemTitle>
                                                    </MListItemContent>
                                                </ItemContent>
                                            </MListItem>
                                        </MCol>
                                        <MDivider Vertical Center />
                                        <MCol>
                                            <MLabel Class=@($"{(item.ResultID.Failed()?"red--text":"green--text")} ma-1")> @item.Value  </MLabel>
                                        </MCol>

                                    </MRow>
                                </MSheet>
                            }

                        }


                    </ScrollXTransition>

                }
            </MCardText>
        </MCol>

        <MDivider Vertical></MDivider>

    </MRow>


</MCard>
<MOverlay Absolute Value="overlay" Opacity="0.8">
    <span class="green--text text--darken-2">
        @("正在获取OPCDA节点...")
    </span>
    <MProgressCircular Indeterminate Width=6
                       Size="30"></MProgressCircular>
</MOverlay>
@code
{

    protected override void OnInitialized()
    {
        Task.Run(async () =>
        {
            Nodes = PopulateBranch("");
            overlay = false;
            await InvokeAsync(StateHasChanged);
        });
    }
    private bool overlay = true;
    [Parameter]
    public ThingsGateway.Foundation.Adapter.OPCDA.OPCDAClient PLC { get; set; }
    private List<OPCDATagModel> Nodes = new();
    private List<BrowseElement> _selected { get; set; } = new();
    private List<BrowseElement> actived = new();
    private ItemProperty[] nodeAttributes;
    private List<BrowseElement> _actived
    {
        get => actived;
        set
        {
            if (actived?.FirstOrDefault() != value?.FirstOrDefault() && value?.Count > 0)
            {
                actived = value;
                nodeAttributes = actived.FirstOrDefault().Properties;
            }

        }

    }
    [Inject]
    IDriverPluginService DriverPluginService { get; set; }
    private Task PopulateBranchAsync(OPCDATagModel model)
    {
        return Task.Run(() =>
        {
            var sourceId = model.Tag.ItemName;
            model.Nodes = PopulateBranch(sourceId);
        });

    }
    public CollectDevice GetImportDevice()
    {
        var data =
               new CollectDevice()
                   {
                       Name = PLC.OPCNode.OPCName + YitIdHelper.NextId().ToString(),
                       Id = YitIdHelper.NextId(),
                       Enable = true,
                       IsLogOut = true,
                       DevicePropertys = new(),
                       PluginId = DriverPluginService.GetIdByName("ThingsGateway.OPCDA.OPCDAClient").ToLong(),
                   };

        data.DevicePropertys.Add(new() { PropertyName = nameof(OPCDAClientProperty.OPCName), Value = PLC.OPCNode.OPCName, Description = typeof(OPCDAClientProperty).GetProperty(nameof(OPCDAClientProperty.OPCName)).GetCustomAttribute<DevicePropertyAttribute>().Name });
        data.DevicePropertys.Add(new() { PropertyName = nameof(OPCDAClientProperty.OPCIP), Value = PLC.OPCNode.OPCIP, Description = typeof(OPCDAClientProperty).GetProperty(nameof(OPCDAClientProperty.OPCIP)).GetCustomAttribute<DevicePropertyAttribute>().Name });
        data.DevicePropertys.Add(new() { PropertyName = nameof(OPCDAClientProperty.ActiveSubscribe), Value = PLC.OPCNode.ActiveSubscribe.ToString(), Description = typeof(OPCDAClientProperty).GetProperty(nameof(OPCDAClientProperty.ActiveSubscribe)).GetCustomAttribute<DevicePropertyAttribute>().Name });
        data.DevicePropertys.Add(new() { PropertyName = nameof(OPCDAClientProperty.CheckRate), Value = PLC.OPCNode.CheckRate.ToString(), Description = typeof(OPCDAClientProperty).GetProperty(nameof(OPCDAClientProperty.CheckRate)).GetCustomAttribute<DevicePropertyAttribute>().Name });
        data.DevicePropertys.Add(new() { PropertyName = nameof(OPCDAClientProperty.DeadBand), Value = PLC.OPCNode.DeadBand.ToString(), Description = typeof(OPCDAClientProperty).GetProperty(nameof(OPCDAClientProperty.DeadBand)).GetCustomAttribute<DevicePropertyAttribute>().Name });
        data.DevicePropertys.Add(new() { PropertyName = nameof(OPCDAClientProperty.GroupSize), Value = PLC.OPCNode.GroupSize.ToString(), Description = typeof(OPCDAClientProperty).GetProperty(nameof(OPCDAClientProperty.GroupSize)).GetCustomAttribute<DevicePropertyAttribute>().Name });
        data.DevicePropertys.Add(new() { PropertyName = nameof(OPCDAClientProperty.UpdateRate), Value = PLC.OPCNode.UpdateRate.ToString(), Description = typeof(OPCDAClientProperty).GetProperty(nameof(OPCDAClientProperty.UpdateRate)).GetCustomAttribute<DevicePropertyAttribute>().Name });
        return data;
    }

    public (CollectDevice, List<CollectDeviceVariable>) GetImportVariableList()
    {
        var device = GetImportDevice();
        var data = _selected.Select(a =>
          {
              ProtectTypeEnum level = ProtectTypeEnum.ReadOnly;
              try
              {
                  var userAccessLevel = (accessRights)(a.Properties.FirstOrDefault(b => b.ID.Code == 5).Value);
                  level = userAccessLevel == accessRights.readable ? userAccessLevel == accessRights.writable ?
         ProtectTypeEnum.WriteOnly : ProtectTypeEnum.ReadOnly : ProtectTypeEnum.ReadWrite;
              }
              catch
              {

              }
              return new CollectDeviceVariable()
                  {
                      Name = device.Name + "_" + a.Name,
                      VariableAddress = a.ItemName,
                      DeviceId = device.Id,
                      Id = Yitter.IdGenerator.YitIdHelper.NextId(),
                      ProtectTypeEnum = level,
                      IntervalTime = 1000,
                  };

          }).Where(a => a != null).ToList();
        return (device, data);
    }

    private List<OPCDATagModel> PopulateBranch(string sourceId)
    {
        List<OPCDATagModel> nodes = new List<OPCDATagModel>();
        nodes.Add(new OPCDATagModel() { Name = "Browsering..." });

        var result = PLC.GetBrowse(sourceId);
        if (!result.IsSuccess) 
        {
            return new() { new() { Name = "未完成连接", Tag = new(),Nodes=null } };
        }
        var references = result.Content;
        List<OPCDATagModel> list = new List<OPCDATagModel>();
        if (references != null)
        {
            for (int ii = 0; ii < references.Count; ii++)
            {
                var target = references[ii];
                OPCDATagModel child = new OPCDATagModel { Name = target.Name };
                child.Tag = target;

                if (target.HasChildren)
                {
                    child.Nodes = PopulateBranch(target.ItemName);
                }
                else
                {
                    child.Nodes = null;
                }
                list.Add(child);
            }
        }

        List<OPCDATagModel> listNode = list;

        nodes.Clear();
        nodes.AddRange(listNode.ToArray());
        return nodes;
    }


    internal class OPCDATagModel
    {
        internal string Name { get; set; }
        internal BrowseElement Tag { get; set; }
        internal string NodeId => (Tag.ItemName).ToString();
        internal List<OPCDATagModel> Nodes { get; set; } = new();
    }
}